/**
 * Debug.java
 *
 * @author BJ Premore
 */


package SSF.OS.OSPF;


import SSF.OS.BGP4.Util.StringManip;  // take StringManip out of BGP4!


// ======================== class SSF.OS.OSPF.Debug ======================== //
/**
 * Encapsulates and manages some debugging information and methods specific to
 * OSPF.
 */
public class Debug {

  // ......................... constants ........................... //

  // ........................ member data .......................... //

  /** The OSPF protocol session object associated with this debugging
   *  manager. */
  private sOSPF ospf;


  // --------------------------- constructor Debug ------------------------- //
  /**
   * Constructs a debugging manager for a given OSPF instance.
   *
   * @param o  The OSPF instance with which this debug object is associated.
   */
  Debug(sOSPF o) {
    ospf = o;
  };

  // ----------------------------- Debug.hdr ------------------------------- //
  /**
   * Constructs a standardized output format prefix.
   *
   * @return the standardized output prefix as a String
   */
  public final String hdr() {
    double t = ospf.nowsec();
    String wsa = StringManip.ws(12 - (""+t).length());
    String wsb = StringManip.ws(8 - ospf.nh.length());
    String str = "";
    return (t + wsa + "ospf@" + ospf.nh + wsb);
  }

  // --------------------- Debug.affirm(boolean,String) -------------------- //
  /**
   * Each of the variations of <code>affirm</code> and <code>gaffirm</code>
   * assert the truth of the given boolean, and print out a message if it is
   * false.  <code>gaffirm</code> is for "generic affirm," since it is static
   * and doesn't print out the associated OSPF instance's info.  This method
   * was called <code>assert</code> in previous versions, but
   * <code>assert</code> became a Java keyword as of Java 1.4.0.
   *
   * @param b  The boolean whose truth is asserted.
   * @param s  The string printed when the boolean is false.
   */
  public final void affirm(boolean b, String s) {
    if (!b) {
      throw new Error(hdr() + s);
    }
  }

  /** See comments for <code>affirm(boolean,String)</code>. */
  public final void affirm(boolean b) {
    affirm(b, "an unspecified error occurred");
  }

  /** See comments for <code>affirm(boolean,String)</code>. */
  public static final void gaffirm(boolean b, String s) {
    if (!b) {
      throw new Error("OSPF ERROR: " + s);
    }
  }

  /** See comments for <code>affirm(boolean,String)</code>. */
  public static final void gaffirm(boolean b) {
    gaffirm(b, "OSPF ERROR: an unspecified error occurred");
  }

  // ------------------------------ Debug.err ------------------------------ //
  /**
   * Reports an OSPF-related error.
   *
   * @param str  The string to be printed along with an error message preamble.
   */
  public final void err(String s) {
    System.err.println(hdr() + "ERROR: " + s);
  }

  // ------------------------------ Debug.gerr ----------------------------- //
  /**
   * A generic function for reporting OSPF-related errors which are not
   * associated with a particular OSPF instance.
   *
   * @param str  The string to be printed along with a generic OSPF error
   *             message preamble.
   */
  public static final void gerr(String str) {
    System.err.println("OSPF ERROR: " + str);
  }

  // ------------------------------ Debug.warn ----------------------------- //
  /**
   * Reports an OSPF-related warning.
   *
   * @param str  The string to be printed as a warning message with an OSPF
   *             warning message preamble.
   */
  public final void warn(String s) {
    System.err.println(hdr() + "Warning: " + s);
  }

  // ----------------------------- Debug.gwarn ----------------------------- //
  /**
   * A generic function for reporting OSPF-related warnings which are
   * not associated with a particular OSPF instance.
   *
   * @param str  The string to be printed as a warning message with a
   *             generic OSPF warning message preamble.
   */
  public static final void gwarn(String str) {
    System.err.println("OSPF Warning: " + str);
  }

  // --------------------------- Debug.msg(String) ------------------------- //
  /**
   * Prints a debugging message in the standardized format.
   */
  public final void msg(String s) {
    System.out.println(hdr() + s);
  }

  // ------------------------------ Debug.msg ------------------------------ //
  /**
   * Each variation of the <code>msg</code> method, except for the
   * one-argument variation which takes a String, calls the
   * <code>Options</code> class method to handle printing a debug
   * message.
   *
   * @param msgtype  A constant indicating the type of debug message.
   * @param caseno   A case number, applicable to certain message types.
   * @param i        meaning varies depending on the message type
   * @param i2       meaning varies depending on the message type
   * @param o        meaning varies depending on the message type
   * @param o2       meaning varies depending on the message type
   */
  public final void msg(int msgtype, int caseno, int i, int i2,
                        Object o, Object o2) {
    if (Options.debugging_on) {
      Options.debugmsg(ospf, msgtype, caseno, i, i2, o, o2);
    }
  }

  /** @see #msg(int,int,int,int,Object,Object) */
  public final void msg(int msgtype) {
    msg(msgtype, -1, -1, -1, null, null);
  }

  /** @see #msg(int,int,int,int,Object,Object) */
  public final void msg(int msgtype, int caseno) {
    msg(msgtype, caseno, -1, -1, null, null);
  }

  /** @see #msg(int,int,int,int,Object,Object) */
  public final void msg(int msgtype, int caseno, int i) {
    msg(msgtype, caseno, i, -1, null, null);
  }

  /** @see #msg(int,int,int,int,Object,Object) */
  public final void msg(int msgtype, int caseno, int i, int i2) {
    msg(msgtype, caseno, i, i2, null, null);
  }

  /** @see #msg(int,int,int,int,Object,Object) */
  public final void msg(int msgtype, int caseno, int i, int i2, Object o) {
    msg(msgtype, caseno, i, i2, o, null);
  }

  /** @see #msg(int,int,int,int,Object,Object) */
  public final void msg(int msgtype, int caseno, int i, Object o) {
    msg(msgtype, caseno, i, -1, o, null);
  }

  /** @see #msg(int,int,int,int,Object,Object) */
  public final void msg(int msgtype, int caseno, Object o) {
    msg(msgtype, caseno, -1, -1, o, null);
  }

  /** @see #msg(int,int,int,int,Object,Object) */
  public final void msg(int msgtype, int caseno, Object o, Object o2) {
    msg(msgtype, caseno, -1, -1, o, o2);
  }

  /** @see #msg(int,int,int,int,Object,Object) */
  public final void msg(int msgtype, Object o) {
    msg(msgtype, -1, -1, -1, o, null);
  }

  /** @see #msg(int,int,int,int,Object,Object) */
  public final void msg(int msgtype, Object o, Object o2) {
    msg(msgtype, -1, -1, -1, o, o2);
  }

  /** @see #msg(int,int,int,int,Object,Object) */
  public final void msg(int msgtype, double d) {
    msg(msgtype, -1, -1, -1, new Double(d), null);
  }

  /** @see #msg(int,int,int,int,Object,Object) */
  public final void msg(int msgtype, int caseno, double d) {
    msg(msgtype, caseno, -1, -1, new Double(d), null);
  }

  // ------------------------ Debug.valid(int,int) ------------------------- //
  /**
   * Each of the variations of <code>valid</cod> handle printing
   * messages associated with specific OSPF validation tests.
   *
   * @param testnum  The validation test number.
   * @param msgnum   The message number relative to the validation test.
   */
  public final void valid(int testnum, int msgnum) {
    if (Options.debugging_on) {
      Options.validation_msg(ospf, testnum, msgnum, null);
    }
  }

  /** See comments for <code>valid(int,int)</code>. */
  public final void valid(int testnum, int msgnum, Object o) {
    if (Options.debugging_on) {
      Options.validation_msg(ospf, testnum, msgnum, o);
    }
  }


} // end class Debug
